package com.logic.modular.game.player.task.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.comment.exception.ServiceException;
import com.comment.pojo.domain.logic.core.Target;
import com.logic.modular.game.player.bag.service.BagItemServiceImpl;
import com.comment.pojo.domain.logic.domain.PlayerTask;
import com.comment.pojo.domain.logic.core.CoreTaskConfig;
import com.logic.modular.game.statistical.domain.PlayerStatisticalPool;
import com.logic.modular.game.statistical.service.impl.PlayerStatisticalPoolServiceImpl;
import com.logic.modular.gameCore.cultivate.task.service.CoreTaskConfigServiceImpl;
import lombok.extern.slf4j.Slf4j;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.logic.modular.game.player.task.mapper.PlayerTaskMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 玩家任务表(PlayerTask)表服务实现类
 *
 * @author cxy
 * @since 2024-11-05 11:40:54
 */
@Slf4j
@Service
public class PlayerTaskServiceImpl extends ServiceImpl<PlayerTaskMapper, PlayerTask> {
    @Resource
    private CoreTaskConfigServiceImpl coreTaskConfigService;
    @Resource
    private BagItemServiceImpl bagItemServiceImpl;
    @Resource
    private PlayerStatisticalPoolServiceImpl playerStatisticalPoolServiceImpl;

    /**
     * 刷新任务进度
     *
     * @param playerId 玩家id
     */
    public void tryToUpdateTask(Long playerId) {
        List<PlayerTask> list = list(new LambdaQueryWrapper<PlayerTask>().eq(PlayerTask::getPlayerId, playerId));

        // 删除旧任务
        list.forEach(item -> {
            long count1 = coreTaskConfigService.count(
                    new LambdaQueryWrapper<CoreTaskConfig>().eq(CoreTaskConfig::getId, item.getTaskId())
            );
            if (count1 == 0) {
                removeById(item.getId());
            }
        });

        // 获取当前进度
        PlayerStatisticalPool obtain = playerStatisticalPoolServiceImpl.obtain(playerId);

        // 刷新并添加新任务
        for (CoreTaskConfig coreTaskConfig : coreTaskConfigService.list()) {
            Set<Integer> integers = coreTaskConfig.getTargetValue().keySet();
            PlayerTask playerTask = getOne(new LambdaQueryWrapper<PlayerTask>().eq(PlayerTask::getTaskId, coreTaskConfig.getId()).eq(PlayerTask::getPlayerId, playerId));
            if (playerTask == null) {// 如果任务不存在，则添加
                playerTask = new PlayerTask();
                addOrReduceTask(playerId, coreTaskConfig, playerTask, obtain);
            } else if (playerTask.progress == null) {
                addOrReduceTask(playerId, coreTaskConfig, playerTask, obtain);
            } else {// 如果任务存在，则更新
                PlayerTask finalPlayerTask1 = playerTask;
                coreTaskConfig.getTargetValue().forEach((statisticalId, needValue) -> {
                    Long currentValue = obtain.conditionValue2.get(statisticalId);
                    Target target;
                    if (!integers.contains(statisticalId)) { // 如果没有这个任务，则添加
                        target = new Target(currentValue, needValue);
                    } else {
                        target = finalPlayerTask1.progress.get(statisticalId);
                        target.setHasValue(currentValue);
                        if (!target.isComplete()) {
                            target.flush(currentValue, needValue);
                        }
                    }
                    finalPlayerTask1.progress.put(statisticalId, target);
                });
                playerTask.checkProgress();
                playerTask.updateById();
            }
        }
    }

    private void addOrReduceTask(Long playerId, CoreTaskConfig coreTaskConfig, PlayerTask playerTask, PlayerStatisticalPool obtain) {
        playerTask.setPlayerId(playerId);
        playerTask.setTaskId(coreTaskConfig.getId());
        playerTask.setPid(coreTaskConfig.getPid());
        playerTask.setGrouping(coreTaskConfig.getGrouping());
        playerTask.setProgress(new HashMap<>());
        coreTaskConfig.getTargetValue().forEach((statisticalId, needValue) -> {
            Long currentValue = obtain.conditionValue2.get(statisticalId);
            Target target = new Target(currentValue, needValue);
            playerTask.progress.put(statisticalId, target);
        });
        playerTask.setIsFinish(0);
        playerTask.setIsReceive(0);
        saveOrUpdate(playerTask);
    }


    public List<PlayerTask> list(Long playerId) {
        tryToUpdateTask(playerId);
        return list(new LambdaQueryWrapper<PlayerTask>().eq(PlayerTask::getPlayerId, playerId));
    }

    /**
     * 领取任务奖励
     *
     * @param playerId 玩家id
     * @param taskId   任务id
     * @return 玩家任务信息
     */
    public PlayerTask claimTaskRewards(Long playerId, Long taskId) {
        tryToUpdateTask(playerId);

        PlayerTask playerTask = list(playerId).stream()
                .filter(item -> item.getTaskId().equals(taskId))
                .findFirst().orElse(null);

        if (playerTask == null) {
            throw new ServiceException("任务不存在");
        }
        if (playerTask.getIsFinish() != 1) {
            throw new ServiceException("任务未完成", playerTask);
        }
        if (playerTask.getIsReceive() == 1) {
            throw new ServiceException("奖励已领取");
        }

        CoreTaskConfig coreTaskConfig = coreTaskConfigService.getCache(taskId);
        Map<Long, Long> rewardProp = coreTaskConfig.getRewardProp();
        if (rewardProp.isEmpty()) {
            throw new ServiceException("奖励为空");
        }

        rewardProp.forEach((propId, num) -> bagItemServiceImpl.obtainBagItem(playerId, propId, BigDecimal.valueOf(num)));

        playerTask.setIsReceive(1);
        playerTask.updateById();
        return playerTask;
    }
}
